home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / dns / rovers / Displays / Display.c next >
Encoding:
C/C++ Source or Header  |  1991-05-06  |  27.3 KB  |  919 lines

  1.  /************************************************************************
  2.  *            Display.c    Display Current Problems     *
  3.  *                                    *
  4.  *       This program displays the problems in a format useful to    *
  5.  *    the operators.  There is a date and time field for when the    *
  6.  *    problem occured, and an Update command so that a problem    *
  7.  *    status can be carried across operator shifts.  Each Update    *
  8.  *     appends a timestamped event to the pingky.log file as well.    *
  9.  *                                    *
  10.  *       This Display program may be modified to the installations    *
  11.  *    specifications without modifying the background data collection.*
  12.  *                                    *
  13.  *       I encourage programmers to make additions to this code and    *
  14.  *    forward them to me for inclusion in the next release.        *
  15.  *                                    *
  16.  ************************************************************************
  17.  * Author:   WB Norton    4/23/89        Merit Computer Network        *
  18.  *                                    *
  19.  *    Version 1.0   Author: WB Norton, Merit Computer Network         *
  20.  *                                    *
  21.  * Modification History:                        *
  22.  * Written 5/18/89 Bill Norton, Merit Computer Network                  *
  23.  *                                    *
  24.  ************************************************************************/
  25. /*
  26.   * Copyright 1989
  27.   * The Regents of the University of Michigan
  28.   * All Rights eserved
  29.   *
  30.   * Permission to use, copy, modify, and distribute this software and its
  31.   * documentation for any purpose and without fee is hereby granted, provided
  32.   * that the above copyright notice and this permission notice appear in
  33.   * all copies of the software and derivative works or modified versions
  34.   * thereof, and that both that copyright notice and this permission
  35.   * notice appear in supporting documentation.
  36.   *
  37.   * The software is provided "as is" and the University of Michigan
  38.   * disclaims all warranties with regard to this software, including
  39.   * all implied warranties of merchantability and fitness.  In no event
  40.   * shall the University of Michigan be liable for any special, direct,
  41.   * indirect, or consequential damages or any damages whatsoever
  42.   * resulting from loss of use, data or profits, whether in an action of
  43.   * contract, negligence or other tortious action, arising out of or in
  44.   * connection with the use or performance of this software.
  45.   */
  46.  
  47. #include "../ProblemManager/ProblemManager.h"
  48. #include "../Ctools/ctools.h"
  49. #include "version.h"
  50. #include <curses.h>
  51. #ifdef AIX
  52. #include <term.h>
  53. #endif
  54. #include <time.h>
  55. #include <signal.h>
  56. #include <ctype.h>
  57. #include <string.h>
  58. #include <sys/file.h>
  59. #include <unistd.h>
  60.  
  61. #define HUMANTIME 1
  62. #define ELAPSEDMIN 2
  63. #define ELAPSEDSEC 3
  64. #define LONGTIME 4
  65. static int TimeStampFormat=HUMANTIME;
  66.  
  67. static int CurrentLine=0;
  68.  
  69. static char *title="NOC Display";
  70. static char *DefaultPingkyDir=".";
  71. static char hostfile[100];        /* List of nodes we are checking */
  72. static char Checking_File[100];        /* What node are we checking? */
  73. static char ProblemFile[100];        /* Problem File! */
  74. static char cycletime[100];        /* How long did pingky take to cycle */
  75. static char logfile[100];        /* Where do we log things */
  76. static char DisplayType[40];        /* Where do we log things */
  77. static char Filter_File[100];        /* Filter out/in Nodes based on regexp*/
  78.  
  79. static char *tz;
  80. static char *Defaulttz="GMT";
  81.  
  82. #define MAXFILTERS 12
  83. struct Filters {
  84.         char *Name;             /* Name on PushButton */
  85.         char *RegExp;           /* NodeName Reg Exp   */
  86.         char *Pattern;          /* Compiled pattern   */
  87.         int  Selected;           /* Is this net selected*/
  88.         int count;              /* Count of items in net*/
  89. } Filter[MAXFILTERS];
  90.  
  91.         /* Update Interval : How often do we check to see if the */
  92.         /*                   problem file changed.         */
  93. #define UPDATEINTERVAL 15 /* Check for PROBLEM.FILE changes every 15 secs*/
  94.  
  95. static char Updating=0;    /* Don't refresh screen during user update/delete */
  96. static char Updateable=0;    /* Don't Allow updating by default */
  97.  
  98.  
  99. SetupFilters()
  100. {
  101. FILE *stream;
  102. int i,line;
  103. static char inbuffer[MAXFILTERS][100];
  104. char buffer[200];
  105.  
  106.         for( i=0; i<MAXFILTERS; i++ ) Filter[i].Name=NULL;
  107.  
  108.         if ( ( stream = fopen( Filter_File, "r" )) == NULL ) return;
  109.  
  110.         for(i=0,line=1; fgets( inbuffer[i], 100, stream ) != NULL; line++) {
  111.                 if (inbuffer[i][0] == '#' ) continue;
  112.                 if ((Filter[i].Name=strtok(inbuffer[i]," \t\n"))==NULL) {
  113.                         fprintf(stderr,"Blank Line  in filter file: %s line %d \n",Filter_File, line);
  114.                         continue; /*BLANK*/
  115.                 }
  116.  
  117.                 if ((Filter[i].RegExp=strtok(NULL," \t\n"))==NULL) {
  118.                         fprintf(stderr,"NULL Regular Expression in filterfile: %s line %d (%s)\n",Filter_File, line,Filter[i].Name );
  119.                         Filter[i].Name=NULL;
  120.                         continue;
  121.                 }
  122. #ifdef AIX
  123.                 if ( ( Filter[i].Pattern = regcmp( Filter[i].RegExp, NULL ) ) == NULL ) {
  124. #endif
  125. #ifndef AIX
  126.                 if ( ( Filter[i].Pattern = re_comp( Filter[i].RegExp ) ) != NULL ) {
  127. #endif
  128.                         fprintf(stderr,"Error compiling %s regexp %s (%s)\n",Filter[i].Name, Filter[i].RegExp,Filter[i].Name);
  129.  
  130.                         Filter[i].Name=NULL;
  131.                         continue;
  132.                 }
  133. /*printf("Line %d: Filter[i].Name=%s Filter[i].RegExp=%s\n",line,Filter[i].Name,Filter[i].RegExp);*/
  134.                 Filter[i].Selected=TRUE;
  135.                 Filter[i].count=0;
  136.                 if ( i++ >= MAXFILTERS ) {
  137.                         fprintf(stderr,"TOO MANY FILTERS in FILTER FILE %s (MAX=%d)\nIgnoring the rest\n",Filter_File, MAXFILTERS);
  138.                         break;
  139.                 }
  140.         }
  141.         fclose(stream);
  142. }
  143.  
  144.  
  145. /********************************************************
  146.  * PrintTime:  Print the current time on the screen.    *
  147.  ********************************************************/
  148. Print_Time()        /* Print the current time on the screen */
  149. {
  150. long TimeNow;
  151. char buffer[27];
  152. struct tm *tm;
  153.  
  154.     time( &TimeNow );
  155.     strcpy(buffer,ctime( &TimeNow ));
  156.     buffer[16]='\0';
  157.     strcat(buffer," ");
  158.     strcat(buffer,tz);
  159.     buffer[20]='\0';
  160.         mvaddstr(0,59,buffer); 
  161.     tm=gmtime( &TimeNow );
  162.     strcpy(buffer,asctime(tm));
  163.     buffer[16]='\0';
  164.     strcat(buffer," GMT");
  165.         mvaddstr(1,59,buffer); 
  166. }
  167.  
  168. #define SECSDAY (60*60*24)
  169. #define SECSHR    (60*60)
  170. #define SECSMIN    60
  171.  
  172. char *ElapsedMins( diff )
  173. long diff;        /* Elapsed Seconds */
  174. {
  175. static char buffer[20];
  176. int     ElapsedDay,ElapsedHr,ElapsedMin;
  177.  
  178.     if (ElapsedDay= diff / SECSDAY ) diff %= (ElapsedDay*SECSDAY);
  179.     if (ElapsedHr = diff / SECSHR ) diff %= (ElapsedHr*SECSHR);
  180.     ElapsedMin= diff / SECSMIN;
  181.     if ( ElapsedDay ) sprintf( buffer,"%d:%2.2d:%2.2d",
  182.                 ElapsedDay,ElapsedHr,ElapsedMin );
  183.     else
  184.         if ( ElapsedHr ) sprintf( buffer,"%d:%2.2d",
  185.                 ElapsedHr,ElapsedMin );
  186.         else
  187.             if ( ElapsedMin ) sprintf( buffer,"%d",
  188.                         ElapsedMin );
  189.             else sprintf(buffer,"%d",0);
  190.     return( buffer );
  191. }
  192.  
  193. char *PrintTimeStamp( TimeStamp )
  194. long TimeStamp;
  195. {
  196. static char buffer[50];
  197. long TimeNow;
  198.  
  199.     switch( TimeStampFormat ) {
  200.     case LONGTIME:    return( ltoa( TimeStamp, buffer ) );
  201.                 /*NOTREACHED*/
  202.     case HUMANTIME:    sprintf(buffer,"%s_%s ",
  203.                     _Day( TimeStamp ), _Time( TimeStamp ));
  204.                 return( buffer );
  205.                 /*NOTREACHED*/
  206.     case ELAPSEDMIN:    time( & TimeNow );
  207.                 /*return( ltoa( (TimeNow-TimeStamp)/60, buffer) );*/
  208.                 return( ElapsedMins(TimeNow-TimeStamp) );
  209.                 /*NOTREACHED*/
  210.     case ELAPSEDSEC:    time( & TimeNow );
  211.                 return( ltoa( (TimeNow-TimeStamp), buffer ) );
  212.                 /*NOTREACHED*/
  213.     default:        return("BADCALL");
  214.                 /*NOTREACHED*/
  215.     }
  216. }
  217.     
  218. /**********************************************************
  219.  *  Message: Put a message to the user on the bottom line * 
  220.  **********************************************************/
  221. void Message(msg)
  222. char msg[];
  223. {
  224.    standout();
  225.    mvaddstr(LINES-1,0,msg);
  226.    standend();
  227.    clrtoeol();
  228.    refresh();
  229. }
  230.  
  231. /********************************************************
  232.  * DrawFrame: Draw a frame in which problems get logged    *
  233.  ********************************************************/
  234. DrawFrame()
  235. {
  236. char TopLine[80],buffer[80],buf2[20];
  237. int i;
  238.  
  239.     clear(); 
  240.     sprintf(TopLine,"%s          %s",DisplayType,title);
  241.     mvaddstr(0,0,TopLine);
  242.     strcpy(buffer,"Filters: ");
  243.     for( i=0; i<MAXFILTERS && Filter[i].Name!=NULL; i++) 
  244.     if (Filter[i].Selected==FALSE) {
  245.         strcat(buffer,Filter[i].Name); strcat(buffer," ");
  246.         /*strcat(buffer,"("); strcat(buffer,itoa(Filter[i].count,buf2)); strcat(buffer,") ");*/
  247.     }
  248.     if ( strlen(buffer)>9) mvaddstr(2,10,buffer);
  249.     switch( TimeStampFormat ) {
  250.     case HUMANTIME:
  251.     mvaddstr(3,0,"# Reported                Problem                          StatusLine"); 
  252.     break;
  253.     case LONGTIME:
  254.     mvaddstr(3,0,"# longtime            Problem                          StatusLine");
  255.         break;
  256.     case ELAPSEDSEC:
  257.     mvaddstr(3,0,"# ElapsedSecs            Problem                          StatusLine");
  258.         break;
  259.     case ELAPSEDMIN:
  260.     mvaddstr(3,0,"# Elapsed Time            Problem                          StatusLine");
  261.         break;
  262.     default:
  263.         break;
  264.     }    
  265.  
  266.     mvaddstr(4,0,"  ========= --------------------------------------  --------------------------");
  267. }
  268.  
  269. /**************************************************************************
  270.  *  PrintCycleTime: Print the current cycle time of the background pingky * 
  271.  **************************************************************************/
  272. PrintCycle_Time()
  273. {
  274. FILE *stream;
  275. char buffer[10];
  276.  
  277.    mvaddstr(1,0,"Cycle Time:");
  278.    if ((stream=fopen(cycletime,"r"))==NULL) mvaddstr(1,12,"--:--");
  279.    else {
  280.       if (fgets(buffer,10,stream)==NULL) mvaddstr(1,12,"--:--");
  281.       else mvaddstr(1,12,buffer);
  282.       fclose(stream);
  283.    }
  284. }
  285.  
  286. /******************************************************************
  287.  * ReadChecking:  See what node the background pingky is querying *
  288.  ******************************************************************/
  289. ReadChecking()
  290. {
  291. FILE *stream;
  292. char buffer[100];
  293. char buffer2[100];
  294. long timenow;
  295. char CollectorStatus[200];
  296.  
  297.    if ((stream=fopen(Checking_File,"r"))==NULL) {
  298.       perror("Checking_File NOT FOUND! Error: Possibly no Data Collectors!");
  299.    }
  300.    else {
  301.       fgets(CollectorStatus,sizeof(CollectorStatus),stream);
  302.       mvaddstr(LINES-1,0,"Collector:  ");
  303.       mvaddstr(LINES-1,12,CollectorStatus); clrtoeol();
  304.       sprintf(buffer,"%3.3s",&CollectorStatus[18]);
  305.       mvaddstr(2,71,buffer);
  306.       fclose(stream);
  307.       time( &timenow );
  308.       if ( timenow - LastMod( Checking_File ) > 60*5  ) {
  309.         mvaddstr(LINES-1,0,"COLLECTOR has NOT BEEN RUNNING FOR AT LEAST 5 MINUTES!!");
  310.         sprintf(buffer2,"** Collector Died %16.16s RIP **",CollectorStatus);
  311.         mvaddstr(1,20,buffer2);
  312.       }
  313.    }
  314. }
  315.  
  316. /*****************************************************************
  317.  * ReadProblems:  Read Problems and Display on the screen nicely *
  318.  *****************************************************************/
  319. ReadProblems()
  320. {
  321.     Problem_Manager( CHECK, NULL, NULL, NULL, NULL ); /* Reread prob list */
  322.     DrawProblems();
  323. }
  324.  
  325. /*
  326.  *      Filter - Actual Filter Routine ( called for each problem entry
  327.  */
  328. int FilterProblem( p )
  329. struct ProblemType *p;
  330. {
  331. extern char *regex();
  332. int i;
  333.  
  334.         for( i=0; Filter[i].Name!=NULL; i++ ) {
  335. #ifndef AIX
  336.                 re_comp( Filter[i].RegExp );
  337.                 if ( re_exec( p->Name ) == 1 ) {
  338. #endif
  339. #ifdef AIX
  340.                 if ( regex( Filter[i].Pattern, p->Name ) != NULL ) {
  341. #endif
  342.                         Filter[i].count++;
  343.                         if ( Filter[i].Selected==FALSE) {
  344.                                 /*printf("Filtered out %s Node %s\n", Filter[i].Name, p->Name);*/
  345.                                 return(0);
  346.                         }
  347.                         else return(1); /* Matches pattern -user wants to see */
  348.                 }
  349.                 else;   /* See if we match the next one */
  350.         }
  351.         return(1);      /* No Match - user wants to see */
  352. }
  353.  
  354.  
  355. /****************************************************************
  356.  * DrawProblems:  Draw Problems on the screen in a nice format    *
  357.  ****************************************************************/
  358. DrawProblems()
  359. {
  360. int i=0,y=5;
  361. char buffer[100];
  362. extern struct ProblemType ProblemArray[];/*In Coreversion of existing problems*/
  363. extern int NumProblems;
  364.  
  365.   for( i=0; i<MAXFILTERS; i++ ) Filter[i].count=0;
  366.   sprintf(buffer,"[%3d]",NumProblems);
  367.   mvaddstr(2,74,buffer); 
  368.    if ( CurrentLine > NumProblems ) CurrentLine=0;
  369.    if (NumProblems==0) { 
  370.       move(y,0);clrtoeol();
  371.       mvaddstr(y++,30,"**** No Problems ****");
  372.       CurrentLine=0;
  373.    }
  374.    else {
  375.     if ( CurrentLine <= 0 ) {    /* Not scrolling now */
  376.         for(i=0; (i<NumProblems) && (y<LINES-2); i++,y++) {
  377.            if ( FilterProblem( &ProblemArray[i] ) == 1 ) {
  378.             sprintf(buffer,"%2.2d",i+1);
  379.             mvaddstr(y,0,buffer);
  380.                  sprintf(buffer," %9.9s %s %s %s",
  381.                 PrintTimeStamp( ProblemArray[i].TimeStamp ),
  382.                           ProblemArray[i].Name,ProblemArray[i].UniqueID,
  383.                 ProblemArray[i].TestName);
  384.                  mvaddstr(y,3,buffer);
  385.              clrtoeol();
  386.             if ( ProblemArray[i].StatusLine[0] != '\0' )
  387.                      mvaddstr(y,STATUSX,ProblemArray[i].StatusLine);
  388.            }
  389.                else y--;    /* ProblemFiltered*/
  390.         }
  391.     }
  392.     else {
  393.                 for(i=CurrentLine; i<NumProblems && y<LINES-2; i++,y++) {
  394.            if ( FilterProblem( &ProblemArray[i] ) == 1 ) {
  395.             /*if ( ProblemArray[i].StatusLine[0] == '\0' ) standout();*/
  396.             sprintf(buffer,"%2.2d",i+1);
  397.             mvaddstr(y,0,buffer);
  398.             /*if ( ProblemArray[i].StatusLine[0] == '\0' ) standend();*/
  399.                         sprintf(buffer," %9.9s %s %s %s",
  400.                                 PrintTimeStamp( ProblemArray[i].TimeStamp ),
  401.                                 ProblemArray[i].Name,ProblemArray[i].UniqueID,
  402.                                 ProblemArray[i].TestName);
  403.                         mvaddstr(y,3,buffer);
  404.                         clrtoeol();
  405.                         mvaddstr(y,STATUSX,ProblemArray[i].StatusLine);
  406.            } else y--;
  407.         }
  408.     }
  409.    } 
  410.    if (i<NumProblems) {
  411.     mvaddstr(2,55,"[ MORE ... ]");
  412.    }
  413.    else {
  414.     mvaddstr(2,55,"            ");
  415.           for(; y<LINES-2; y++) {
  416.          move( y, 0 );
  417.          clrtoeol();
  418.           }
  419.    }
  420. }
  421.  
  422. /****************************************************************
  423.  * GotoCmdLine:  Got the Command Prompt             *
  424.  ****************************************************************/
  425. GotoCmdLine()
  426. {
  427.    move(LINES-2,0); clrtoeol();
  428.    standout();
  429.    addstr("Command:");
  430.    standend();  
  431.    move(LINES-2,9);
  432. }
  433.  
  434. /****************************************************************
  435.  * DrawDynamics:  Redraw what does change            *
  436.  *            time of day                *
  437.  *            cycletime                *
  438.  *            PROBLEM.FILE                *
  439.  *            CHECKING                *
  440.  *            Goto the command line             *
  441.  ****************************************************************/
  442. DrawDynamics()
  443. {
  444.       Print_Time();    /* Update the time of day */
  445.       PrintCycle_Time();/* Update the Cycle Time portion */
  446.       ReadProblems();    /* Update the Problems section  */
  447.       ReadChecking();    /* Update the checking portion */
  448.       GotoCmdLine();    /* Go to the command line and */
  449.       refresh();    /* refresh the screen */
  450. }
  451.  
  452. /****************************************************************
  453.  * RefreshScreen:  Force Update of the user's screen        *
  454.  *           DO NOT CALL THIS ROUTINE!!!!            *
  455.  *           The user callable version is DrawDynamic    *
  456.  *           RefreshScreen should only be called         *
  457.  *           by alarm clock because it restarts the alarm *
  458.  *           and we don't want multiple alarms to go off. *  
  459.  *           once every UPDATEINTERVAL seconds.        *
  460.  ****************************************************************/
  461. RefreshScreen()
  462. {
  463.    if (!Updating) {
  464.     DrawDynamics();    
  465.    }
  466.    else {
  467.     /*system("echo `date` BUSY>>debug");*/
  468.    }
  469.    signal(SIGALRM,RefreshScreen);    /*  Invoke RefreshScreen on alarm  */
  470.    alarm(UPDATEINTERVAL);
  471. }
  472.  
  473. /****************************************************************
  474.  * ClearMessage:  Clear the message line            *
  475.  ****************************************************************/
  476. void ClearMessage()
  477. {
  478.    move(LINES-1,0);
  479.    clrtoeol();
  480.    refresh();
  481. }
  482.  
  483. SetUpdating( claim )
  484. int claim;
  485. {
  486.     if ( claim )
  487.         mvaddstr(2,40,"*Claiming*"); 
  488.     else
  489.         mvaddstr(2,40,"*Updating*"); 
  490.     refresh();
  491.     Updating=1;
  492. }
  493. ClearUpdating()
  494. {
  495.     mvaddstr(2,40,"          "); refresh();
  496.     Updating=0;
  497. }
  498.     
  499.  
  500. /***********************************************************************
  501.  * GetUpdateList: get the user's request to update a list of problems. *
  502.  ***********************************************************************/
  503. int GetUpdateList()
  504. {
  505. char problemID[100];
  506.  
  507.    getstr(problemID);        /*     get the user's string     */
  508.    return(atoi(problemID));
  509. }
  510.  
  511. /****************************************************************
  512.  *        Update - Update the status of a problem        *
  513.  ****************************************************************/
  514. void Update( claim )
  515. int claim;
  516. {
  517. char ProblemList[100];    /* array of nodes to be updated at once */
  518. int i;
  519. char buffer[200];
  520. extern int NumProblems;
  521. extern struct ProblemType ProblemArray[];
  522. char TestName[100], Name[100], UniqueID[100];
  523.  
  524.    for(i=0; i<100; i++) ProblemList[i]=0;   
  525.    if (NumProblems==0) {
  526.       Message("  There are no problems to update, Bonehead!");
  527.       sleep(5);
  528.       ClearMessage();
  529.       return;
  530.    }
  531.    if (Updateable) {
  532.       SetUpdating( claim );
  533.       if ( claim ) {
  534.           Message("   Enter the problem # that you want to Claim");
  535.           mvaddstr(LINES-2,10,"laim Problem # ");
  536.       }
  537.       else {
  538.           Message("   Enter the problem # that you want to Update   ");
  539.           mvaddstr(LINES-2,10,"pdate Problem # ");
  540.       }
  541.       refresh();
  542.       if ((i=GetUpdateList())==0) {
  543.          ClearMessage();
  544.      ClearUpdating();
  545.          Updating=0;
  546.          return;
  547.       }
  548.       if (i>0 && i<=NumProblems) {
  549.      strcpy(Name,ProblemArray[i-1].Name);
  550.      strcpy(TestName,ProblemArray[i-1].TestName);
  551.      strcpy(UniqueID,ProblemArray[i-1].UniqueID);
  552.      if ( claim )
  553.              Message("  Enter your initials and brief note (if any)     ");
  554.      else
  555.              Message("  Enter the StatusLine as you want it to appear   ");
  556.          move(4+i,STATUSX);
  557.          clrtoeol(); 
  558.          refresh();
  559.          getstr(buffer);
  560.      buffer[MAXSTATUSLINE-1]='\0';
  561.      if ( claim )
  562.         Problem_Manager( CLAIM_PROBLEM, TestName, Name, UniqueID, buffer );
  563.      else
  564.         Problem_Manager( UPDATE_PROBLEM, TestName, Name, UniqueID, buffer );
  565.       }
  566.       else { 
  567.          Message("   Illegal Problem Number   ");
  568.          sleep(5);
  569.          ClearMessage();
  570.       } 
  571.       ClearUpdating();
  572.    }
  573. }
  574.  
  575. sigcatcher()
  576. {
  577. extern int In_Critical_Section;
  578.  
  579.     printf("Interrupt. ERR! Don't do that!\n");
  580.     if ( In_Critical_Section ) {
  581.         Log("Display: Interrupt during Fileio",logfile); 
  582.         printf("Display: Interrupt during Fileio - try again",logfile); 
  583.         return;
  584.     }
  585.        signal(SIGALRM,SIG_DFL);
  586.        signal(SIGHUP,SIG_DFL);
  587.        signal(SIGINT,SIG_DFL);
  588.        signal(SIGQUIT,SIG_DFL);
  589.        signal(SIGTERM,SIG_DFL);
  590.        signal(SIGTSTP,SIG_DFL);
  591.     exit( 0 );
  592. }
  593.  
  594. /****************************************************************
  595.  * Loop:  main loop of program.                  *
  596.  *        Set an alarm to go off in 30 seconds        *
  597.  *            and provide address of alarm routine    *
  598.  *        Read the Problem List, Checking file        *
  599.  *        Update the screen and display the current time    *
  600.  *        Forever                        *
  601.  *            Get a key stroke and handle user cmd.    *    
  602.  ****************************************************************/
  603. Loop( )
  604. {
  605. extern int NumProblems;
  606. char ch;
  607.  
  608.    Log("Display Program Starting\n", logfile);
  609.    signal(SIGALRM,RefreshScreen);    /*  Invoke RefreshScreen on alarm  */
  610.    signal(SIGHUP,sigcatcher);        /*  Catch all signals */
  611.    signal(SIGINT,sigcatcher);        /*  Catch all signals */
  612.    signal(SIGQUIT,sigcatcher);        /*  Catch all signals */
  613.    signal(SIGTERM,sigcatcher);        /*  Catch all signals */
  614.    signal(SIGTSTP,sigcatcher);        /*  Catch all signals */
  615.    alarm(UPDATEINTERVAL);        /* Alarm in UPDATEINTERVAL seconds */
  616.    DrawFrame();                /* Start out with Framework */
  617.    while(1) {
  618.     DrawDynamics();            /*Draw the changing part of the screen*/
  619.     switch( getch() ) {
  620.         case 'u':
  621.         case 'U':         /* Update a problem */
  622.             if ( Updateable ) {
  623.                 Update( 0 );
  624.             }
  625.             else { Message("Permission Denied"); sleep(5); }
  626.             break;
  627.         case 'c':        /* Claim a problem */
  628.         case 'C': 
  629.             if ( Updateable ) {
  630.                 Update( 1 );
  631.             }
  632.             else { Message("Permission Denied"); sleep(5); }
  633.             break;
  634.         case 'q':
  635.         case 'Q':
  636.             addstr("uit");
  637.             move(LINES-1,0);
  638.             clrtoeol();
  639.             refresh();
  640.             return;
  641.             /*NOTREACHED*/
  642.         case 'h':
  643.         case 'H':
  644.             if ( Updateable ) {
  645.                 GetHelp();        
  646.                 DrawFrame();    /* Screen got trashed */
  647.                         }
  648.                         else { Message("Permission Denied"); sleep(5); }
  649.             break;
  650.         case 'd':
  651.         case 'D':
  652.             addstr("elete Problem # ");
  653.                         if ( Updateable ) {
  654.                 DeleteProblem();
  655.                         }
  656.                         else { Message("Permission Denied"); sleep(5); }
  657.             break;
  658.         case 'F':
  659.         case 'f':
  660.             addstr("ilter ");
  661.                         if ( Updateable ) {
  662.                 GetFilter();
  663.                 DrawFrame();    /* Frame will get corrupted */
  664.                         }
  665.                         else { Message("Permission Denied"); sleep(5); }
  666.             break; 
  667.         case '>':    /* ^DOWN */
  668.             if ( (CurrentLine + LINES-6 )> NumProblems )
  669.                 CurrentLine=NumProblems-LINES-6;
  670.             else CurrentLine=CurrentLine + LINES-6-1;
  671.             break;
  672.         case '<':    /* ^UP */
  673.             if ( (CurrentLine - LINES-6 ) <=0 )
  674.                 CurrentLine=0;
  675.             else CurrentLine=CurrentLine - LINES-6;
  676.             break;
  677.         case 'T':
  678.         case 't':
  679.             addstr("rouble ticket # ");
  680.                         if ( Updateable ) {
  681.                 GetTroubleTicket();
  682.                 DrawFrame();    /* Frame will get corrupted */
  683.                         }
  684.                         else { Message("Permission Denied"); sleep(5); }
  685.             break; 
  686.         case 'V':
  687.         case 'v':
  688.             addstr("ersion: ");
  689.             Message(Version);
  690.             sleep( 5 );
  691.             break; 
  692.         case '~':    
  693.             if ( ++TimeStampFormat > 2 ) TimeStampFormat=1;
  694.             DrawFrame();    /* Frame will be different */
  695.             break;
  696.         case '?':
  697.             Message("   Cmds: (U)pdate Problem (H)elp (D)eleteProblem (Q)uit (T)t (V)ersion ~<>");
  698.             sleep(5);
  699.             ClearMessage();
  700.             break;
  701.         case ' ':
  702.             DrawFrame();
  703.             break;
  704.         default:  
  705.             refresh();
  706.                     break;
  707.     }    /* switch */ 
  708.    }    /* While () */
  709. }
  710.  
  711. /**********************************************************************
  712.  * DeleteProblem() - Allow User to delete a Problem From the Problem  *
  713.  *                                 File *
  714.  **********************************************************************/
  715. DeleteProblem()
  716. {
  717. char buffer[200],ProblemNumber[100];
  718. int Num;
  719. extern int NumProblems;
  720. extern struct ProblemType ProblemArray[];/*In Coreversion of existing problems*/
  721.  
  722.     SetUpdating( 0 );
  723.         Message("  Enter the Problem # of the Problem you want to Delete");
  724.         move(LINES-2,26);
  725.         refresh();
  726.         getstr(ProblemNumber);
  727.         refresh();
  728.     if ((( Num = atoi(ProblemNumber) ) > NumProblems ) || (Num<1)) {
  729.         Message(" That isn't a valid Problem Number ");
  730.         sleep( 5 );
  731.         ClearUpdating();
  732.         return 0;
  733.     } 
  734.      buffer[199]='\0';
  735.          sprintf(buffer,"%s %s %s %s Problem DELETED BY OPERATOR Old StatusLine: %s\n",
  736.         _Day(ProblemArray[Num-1].TimeStamp),_Time(ProblemArray[Num-1].TimeStamp),
  737.         ProblemArray[Num-1].Name,ProblemArray[Num-1].TestName,
  738.         ProblemArray[Num-1].StatusLine);
  739.          Log(buffer,logfile);
  740.     Problem_Manager( DELETE_PROBLEM, ProblemArray[Num-1].TestName, ProblemArray[Num-1].Name, ProblemArray[Num-1].UniqueID, NULL );
  741.  
  742.         Message(" Done ");
  743.     ClearUpdating();
  744.     return 1;
  745. }
  746.  
  747. GetFilter()
  748. {
  749. char buffer[80],Name[40];
  750. int i;
  751.  
  752.     SetUpdating( 0 );
  753.     strcpy(buffer,"Filters: ");
  754.     for( i=0; i<MAXFILTERS && Filter[i].Name!=NULL && (strlen(buffer)+strlen(Filter[i].Name) < 80); i++) {
  755.         if ( Filter[i].Selected ) strcat(buffer,"*");
  756.         strcat(buffer,Filter[i].Name);
  757.         strcat(buffer," ");
  758.     }
  759.         Message(buffer);
  760.         move(LINES-2,20);
  761.         refresh();
  762.         getstr(Name);
  763.         refresh();
  764.     for( i=0; i<MAXFILTERS && Filter[i].Name!=NULL; i++) {
  765.         if ( strcmp( Name, Filter[i].Name ) == 0 ) {
  766.             Filter[i].Selected^=1; 
  767.             ClearUpdating();
  768.             return;
  769.         }
  770.     }
  771.     Message(" That isn't a valid Filter Name");
  772.     sleep( 3 );
  773.     ClearUpdating();
  774. }
  775.  
  776. /************************************************************************
  777.  *  GetHelp:    Display Help screen for a particular problem node    *
  778.  ************************************************************************/
  779. GetHelp()
  780. {
  781. char ProblemNumber[100];
  782. int Num;
  783. extern int NumProblems;
  784. extern struct ProblemType ProblemArray[];/*In Coreversion of existing problems*/
  785.  
  786.         addstr("elp with problem # ");
  787.         Message("  Enter the Problem # of the Problem you want help with");
  788.         move(LINES-2,30);
  789.         refresh();
  790.         getstr(ProblemNumber);
  791.         refresh();
  792.     if ((( Num = atoi(ProblemNumber) ) > NumProblems ) || (Num<1)) {
  793.         Message(" That isn't a valid Problem Number ");
  794.         sleep( 5 );
  795.         return 0;
  796.     } 
  797.     Help( ProblemArray[Num-1].Name );
  798. }
  799.  
  800. more( NodeName,filename )
  801. char *NodeName;
  802. char *filename;
  803. {
  804. FILE *stream;
  805. char buffer[200];
  806. int i=0;
  807. char ch;
  808.  
  809.     if ((stream=fopen(filename,"r"))==NULL) {
  810.         sprintf(buffer,"Can't open %s - no help available\n",filename);
  811.         Message( buffer );
  812.         return;
  813.     }
  814.     while( fgets( buffer, sizeof(buffer), stream ) != NULL ) {
  815.         printf(buffer);
  816.         if ( ++i >= LINES-1 ) {
  817.             printf("-- %s File : %s    Strike a key when ready... --",NodeName,filename);
  818.             fflush(stdout);
  819.             ch=getch();
  820.             if ((ch=='Q')||(ch=='q')) break;
  821.             printf("\n");
  822.             i=0;
  823.         }
  824.     }
  825.     fclose(stream);
  826. }
  827.  
  828. Help( NodeName )
  829. char *NodeName;
  830. {
  831. FILE *stream;
  832. char buffer[200], *file, *p;
  833. int line=1;
  834.  
  835.     if ((stream=fopen(hostfile,"r"))==NULL) {
  836.         sprintf(buffer,"No hostfile (%s) available - No Help available",
  837.             hostfile );
  838.         Message(buffer);
  839.         return;
  840.     }
  841.     while( ( p=fgets( buffer, sizeof(buffer), stream )) != NULL ) {
  842.         if ( strcmp( NodeName , strtok( buffer," \t\n")) == 0 ) {
  843.             Updating=1;    /* Don't redraw the screen */
  844.             if ( strtok( NULL, " \t\n" ) == NULL ) break;
  845.             if ( (file=strtok( NULL, " \t\n"))==NULL) break;
  846.             clear();
  847.             refresh();
  848.             more(NodeName,file);
  849.             printf("Strike a key when ready..."); fflush(stdout);    
  850.             getch();
  851.             Updating=0;
  852.             return;
  853.         }
  854.         line++;
  855.     }
  856.     if ( p == NULL ) sprintf(buffer," No Help available for Node %s",NodeName);
  857.     else sprintf(buffer," Error in line #%d of hostfile - no help available",line);
  858.     Message( buffer );
  859. }
  860.  
  861. GetTroubleTicket()
  862. {
  863.     clear();
  864.     Message("Trouble Ticket System Not available yet..");
  865.     sleep(5);
  866. }
  867.  
  868. SetUpdateable( file )
  869. char *file;
  870. {
  871.  
  872.     if ( access( file, W_OK | F_OK ) == 0 ) Updateable=1;
  873.     else Updateable=0;
  874. }
  875.  
  876. /************************************************************************
  877.  *   Main Program:     Start up the curses screen package and start     *
  878.  *                command processing loop            *
  879.  ************************************************************************/
  880. char *programname;
  881. main(argc,argv)
  882. int argc;
  883. char *argv[];
  884. {
  885. char *pingkydir,*getenv();
  886. char buffer[100];
  887. int i;
  888.  
  889.     printf("%s\n",Version);
  890.     programname=argv[0];
  891.     for( i=1; i<argc; i++ )
  892.     if ( strcmp( argv[i] , "-T" ) == 0 ) {
  893.         title=argv[i+1];
  894.         i+=2;
  895.     }
  896.     else {
  897.         printf("\n\n\tUsage: %s [ -T Title ]\n",argv[0]);
  898.         exit(1);
  899.     }
  900.     if ((pingkydir=getenv("PINGKYDIR"))==NULL) pingkydir=DefaultPingkyDir;
  901.     if ((tz=getenv("TZ"))==NULL) tz=Defaulttz;
  902.  
  903.     strcpy(Checking_File,pingkydir); strcat(Checking_File,"/CHECKING");
  904.     strcpy(cycletime,pingkydir); strcat(cycletime,"/pingky.cycle");
  905.     strcpy(logfile,pingkydir); strcat(logfile,"/problemlog");
  906.     strcpy(hostfile,pingkydir); strcat(hostfile,"/hostfile");
  907.     strcpy(ProblemFile,pingkydir); strcat(ProblemFile,"/PROBLEM.FILE");
  908.     strcpy(Filter_File,pingkydir); strcat(Filter_File,"/pingky.filter");
  909.     if (getcwd(buffer,100) == NULL ) strcpy(DisplayType,"Unknown");
  910.     else strcpy(DisplayType,strrchr(buffer,'/')+1);
  911.     strcat(DisplayType," "); strncat(DisplayType,Version,13);
  912.     
  913.     SetupFilters();
  914.     SetUpdateable( ProblemFile );
  915.     initscr();            /* Open Up the curses environment      */
  916.     Loop( );    /* Call the main command handling loop       */
  917.     endwin();             /* Close down the curses environment       */
  918. }
  919.